﻿using System;
using System.Collections;
using System.Linq;
using Microsoft.WowAddonStudio.FrameXml.Serialization;
using NUnit.Framework;

namespace Microsoft.WowAddonStudio.FrameXml.Serialization.Tests
{
    [TestFixture]
    public class SimpleSerializationTest : SerializationTestBase
    {
        private Ui ui;

        [TearDown]
        public void TearDown()
        {
            Assert.Counter.ToString();

            if (ui != null && Assert.Counter == 0)
                AssertNoUnknownElements(ui);
        }

        [Test]
        public void EmptyUiTest()
        {
            ui = this.DeserializeUi("Simple/EmptyUi.xml");
        }

        [Test]
        public void UiIncludeTest()
        {
            ui = this.DeserializeUi("Simple/UiInclude.xml");

            Assert.IsNotNull(ui.Includes);
            Assert.AreEqual(2, ui.Includes.Length);
            Assert.AreEqual("EmptyUi.xml", ui.Includes[0].File);
            Assert.AreEqual("UiScript.xml", ui.Includes[1].File);

            AssertNoUnknownElements(ui.Includes);
        }

        [Test]
        public void UiScriptTest()
        {
            ui = this.DeserializeUi("Simple/UiScript.xml");

            Assert.IsNotNull(ui.Scripts);
            Assert.AreEqual(2, ui.Scripts.Length);
            Assert.AreEqual("UiScript.lua", ui.Scripts[0].File);
            Assert.AreEqual("print(\"Hello world!\");", ui.Scripts[1].Value);

            AssertNoUnknownElements(ui.Scripts);
        }

        [Test]
        public void UiFontTest()
        {
            ui = this.DeserializeUi("Simple/UiFont.xml");

            Assert.IsNotNull(ui.Fonts);
            Assert.AreEqual(2, ui.Fonts.Length);
            
            // MasterFont
            Assert.AreEqual("MasterFont", ui.Fonts[0].Name);
            Assert.AreEqual(true, ui.Fonts[0].Virtual);
            Assert.IsNotNull(ui.Fonts[0].Shadow);
            Assert.IsNotNull(ui.Fonts[0].Shadow.Offset);

            // GameFontNormal
            Assert.AreEqual("GameFontNormal", ui.Fonts[1].Name);
            Assert.AreEqual("MasterFont", ui.Fonts[1].Inherits);
            Assert.IsNotNull(ui.Fonts[1].Color);
            Assert.IsNotNull(ui.Fonts[1].FontHeight);
            Assert.AreEqual(12, ui.Fonts[1].FontHeight.Value);

            AssertNoUnknownElements(ui.Fonts);
            AssertNoUnknownElements(ui.Fonts[0].Shadow);
            AssertNoUnknownElements(ui.Fonts[0].Shadow.Offset);
            AssertNoUnknownElements(ui.Fonts[1].FontHeight);
        }

        private static void AssertNoUnknownElements(IEnumerable serializationObjects)
        {
            foreach (var serializationObject in serializationObjects.OfType<SerializationObject>())
                AssertNoUnknownElements(serializationObject);
        }

        private static void AssertNoUnknownElements(SerializationObject serializationObject)
        {
            Assert.IsNull(serializationObject.UnknownElements, "Serialization object '{0}' has unknown elements:\t{1}", serializationObject, 
                serializationObject.UnknownElements != null ? serializationObject.UnknownElements.Aggregate(String.Empty, (seed, element) => seed + (seed.Length > 0 ? ", " : String.Empty) + element.Name)
                                                            : null);
                            
            Assert.IsNull(serializationObject.UnknownAttributes, "Serialization object '{0}' has unknown attributes:\t{1}", serializationObject, 
                serializationObject.UnknownAttributes != null ? serializationObject.UnknownAttributes.Aggregate(String.Empty, (seed, attribute) => seed + (seed.Length > 0 ? ", " : String.Empty) + attribute.Name)
                                                            : null);
        }
    }
}
